import json5 from 'json5';

/**
 * 根据当前环境创建服务配置
 *
 * 该函数从环境变量中读取后端服务的基础 URL 和其他服务的 URL 配置， 并生成完整的服务配置对象，包括代理模式设置
 *
 * @param env 当前环境变量对象
 * @returns 完整的服务配置对象
 */
export function createServiceConfig(env: Env.ImportMeta) {
  const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env;

  // 初始化其他服务的配置对象
  let other = {} as Record<App.Service.OtherBaseURLKey, string>;
  try {
    // 尝试解析其他服务的基础 URL 配置（JSON5 格式）
    other = json5.parse(VITE_OTHER_SERVICE_BASE_URL);
  } catch {
    // 如果解析失败，输出错误信息到控制台
    // eslint-disable-next-line no-console
    console.error('VITE_OTHER_SERVICE_BASE_URL 不是一个有效的 JSON5 字符串');
  }

  // 创建 HTTP 配置对象
  const httpConfig: App.Service.SimpleServiceConfig = {
    baseURL: VITE_SERVICE_BASE_URL, // 主服务的基础 URL
    other // 其他服务的 URL 配置
  };

  // 获取所有其他服务的键名
  const otherHttpKeys = Object.keys(httpConfig.other) as App.Service.OtherBaseURLKey[];

  // 将其他服务配置转换为标准格式，包含代理模式
  const otherConfig: App.Service.OtherServiceConfigItem[] = otherHttpKeys.map(key => {
    return {
      key, // 服务标识
      baseURL: httpConfig.other[key], // 服务的基础 URL
      proxyPattern: createProxyPattern(key) // 对应的代理模式
    };
  });

  // 构建完整的服务配置对象
  const config: App.Service.ServiceConfig = {
    baseURL: httpConfig.baseURL, // 主服务的基础 URL
    proxyPattern: createProxyPattern(), // 默认代理模式
    other: otherConfig // 其他服务的配置列表
  };

  return config;
}

/**
 * 获取后端服务的基础 URL
 *
 * 根据是否启用代理模式，返回相应的服务 URL。 在开发环境中，如果启用了代理，会返回代理路径； 在生产环境中，直接返回实际的服务 URL
 *
 * @param env 当前环境变量对象
 * @param isProxy 是否使用代理模式
 * @returns 包含主服务和其他服务 URL 的对象
 */
export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) {
  // 创建服务配置
  const { baseURL, other } = createServiceConfig(env);

  // 初始化其他服务的 URL 对象
  const otherBaseURL = {} as Record<App.Service.OtherBaseURLKey, string>;

  // 遍历其他服务配置，根据代理模式设置相应的 URL
  other.forEach(item => {
    otherBaseURL[item.key] = isProxy ? item.proxyPattern : item.baseURL;
  });

  // 返回配置结果
  return {
    // 主服务 URL：如果启用代理则使用代理路径，否则使用实际 URL
    baseURL: isProxy ? createProxyPattern() : baseURL,
    // 其他服务的 URL 配置
    otherBaseURL
  };
}

/**
 * 获取后端服务基础 URL 的代理模式
 *
 * 生成用于开发环境代理的路径模式。 如果不指定 key，则使用默认的代理路径； 如果指定了 key，则生成对应的代理路径
 *
 * @param key 服务标识，如果不设置则使用默认标识
 * @returns 代理路径字符串
 */
function createProxyPattern(key?: App.Service.OtherBaseURLKey) {
  if (!key) {
    // 默认代理路径
    return '/proxy-default';
  }

  // 根据服务标识生成对应的代理路径
  return `/proxy-${key}`;
}
